﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using RJ.Objects.GameEngine;

namespace RJ.Objects.PokerCards
{
    public class EuchreDeck : Deck
    {
        private int dealIndex = 0;
        private int currentCardIndex = 0;
        private int dealCount = 0;
        private GameEngine.SpriteSheet cardBackSheet;
        private Rectangle srcBackRect;
        private List<Sprite> destBackSprites;

        private PlayingCard[] redScoringCards;
        public PlayingCard[] RedScoringCards
        {
            get { return redScoringCards.Select(c => c.Copy()).ToArray(); }
        }

        private PlayingCard[] blackScoringCards;
        public PlayingCard[] BlackScoringCards
        {
            get { return blackScoringCards.Select(c => c.Copy()).ToArray(); }
        }

        public PlayingCard TopCardOfLastFour
        {
            get { return shuffledDeck.Skip(currentCardIndex).First(); }
        }

        public int[] DealingPattern;


        public EuchreDeck()
            : this(null, null, null, true) { }

        public EuchreDeck(GameEngine.GameState game,
            GameEngine.SpriteSheet cardSheet,
            Dictionary<string, Point> cardPointDict,
            bool aceIsHigh)
            : this(game, cardSheet, cardPointDict, aceIsHigh, null, 1) { }

        public EuchreDeck(GameEngine.GameState game,
            GameEngine.SpriteSheet cardSheet,
            Dictionary<string, Point> cardPointDict,
            bool aceIsHigh, GameEngine.SpriteSheet cardBackSheet, int cardBack)
            : base(game, cardSheet, cardPointDict, aceIsHigh)
        {
            redScoringCards = cards.Where(c => (int)c.Suit < 3 && (int)c.Face == 5).ToArray();
            blackScoringCards = cards.Where(c => (int)c.Suit > 2 && (int)c.Face == 5).ToArray();

            this.cardBackSheet = cardBackSheet;
            cards = cards.Where(c => (int)c.Face > 8).ToList();
            DealingPattern = new int[] { 2, 3 };

            initializeDeckGraphics(cardBack);
        }

        private void initializeDeckGraphics(int cardBack)
        {
            if (cardBackSheet != null)
            {
                var gs = (this.game as GameEngine.GameState);
                int halfWidth = gs.clientSize.Width / 2;
                int halfHeight = gs.clientSize.Height / 2;
                Size backSize = cardBackSheet.GetDimensions();
                Size cardSize = new Size(backSize.Width / 4, backSize.Height);
                destBackSprites = new List<Sprite>(10);

                srcBackRect = new Rectangle(cardSize.Width * (cardBack - 1), 0, cardSize.Width, cardSize.Height);
                PointF destPoint = new PointF(5, halfHeight - (cardSize.Height / 2));
                int modifier = 2;

                for (int i = 0; i < 10; i++)
                {
                    var sprite = new Sprite(this.game, cardBackSheet, srcBackRect,
                        new RectangleF(destPoint, new SizeF(cardSize.Width, cardSize.Height)), new PointF(0, 0));
                    destBackSprites.Add(sprite);
                    destPoint.X += modifier;
                    destPoint.Y += modifier;
                }
            }
        }

        public List<PlayingCard> DealNextCards()
        {
            ++dealCount;

            List<PlayingCard> dealtCards = shuffledDeck.Skip(currentCardIndex)
                .Take(DealingPattern[dealIndex])
                .ToList();

            currentCardIndex += DealingPattern[dealIndex];

            dealIndex = dealIndex == 0 ? 1 : 0;

            if (dealCount == 4)
            {
                dealIndex = 1;
                dealCount = 0;
            }

            return dealtCards;
        }

        public override void Update(double gameTime, double elapsedTime)
        {
            // nothing to update
        }

        public override void Draw(Graphics g)
        {
            foreach (var dest in destBackSprites)
                cardBackSheet.DrawSprite(g, dest);
        }
    }
}
